#include "timer.h"
#include <xc.h>
#include "../system/system.h"


void __attribute__ ( ( weak) ) Timer1CallBack();
void __attribute__ ( ( weak) ) Timer23CallBack();

//16bits
void Timer1_Initial_g(void)
{
    //    TI: Timer 1
    //    Priority: 1
    IPC0bits.T1IP = 1;
    
    //TMR1 0; 
    TMR1 = 0x0;
    //Period = 0.4 s; Frequency = 40000000 Hz; PR1 62500; 
    
    //TCKPS 1:256; TON enabled; TSIDL disabled; TCS FOSC/2; TSYNC disabled; TGATE disabled; 
    //T1CON = 0x8030;
    T1CONbits.TON = 0; //bit15, timer enable
    T1CONbits.TSIDL = 0; //bit13, timer stop in idle
    T1CONbits.TGATE = 0; //bit6, timer gate acc enable, when tcs=1 ignore TGATE, 0-disable,1-enable
    T1CONbits.TCKPS = 3;//bit5:4, input clock divided,00-1,01-8;10-64,11-256
    T1CONbits.TSYNC = 0; //bit2,ext input clock sysn, when tcs=0 ignore TSYNC, 0-not sync ext clock
    T1CONbits.TCS = 0; //bit1,0-Fp,1-TICK pin clock

    IFS0bits.T1IF = 0;  //clear flag
    IEC0bits.T1IE = 1;  //interrupt enable
}

void Timer1_Start_g( uint16_t ms )
{
    uint16_t div;
    uint32_t period;
    switch(T1CONbits.TCKPS)
    {
        case 0: div=1;break;
        case 1: div=8;break;
        case 2: div=64; break;
        case 3: div=256; break;
        default:div=1;break;
    }
    period = SYSTEM_FOSC/2/div/1000*ms;
    PR1 = period;
    
    /*Enable the interrupt*/
    IEC0bits.T1IE = 1;

    /* Start the Timer */
    T1CONbits.TON = 1;
}

void Timer1_Stop_g( void )
{
    /* Stop the Timer */
    T1CONbits.TON = 0;

    /*Disable the interrupt*/
    IEC0bits.T1IE = 0;
}


//interrupt function


void __attribute__ ( ( interrupt, no_auto_psv ) ) _T1Interrupt (  )
{
    Timer1CallBack();

    IFS0bits.T1IF = 0; //clear flag
}

/**************************************************************/
//32bits
void Timer23_Initial_g(void)
{
    
    T3CONbits.TON = 0; //bit15, timer enable, Stop any 16-bit Timer3 operation
    T2CONbits.TON = 0; //bit15, timer enable, Stop any 16/32-bit Timer3 operation
    T2CONbits.T32 = 1; // Enable 32-bit Timer mode
    T2CONbits.TCS = 0; // Select internal instruction cycle clock
    T2CONbits.TGATE = 0; // Disable Gated Timer mode
    T2CONbits.TCKPS = 0b11; // Select Prescaler,00-1,01-8,10-64,11-256
    TMR3 = 0x00; // Clear 32-bit Timer (msw)
    TMR2 = 0x00; // Clear 32-bit Timer (lsw)
    
    
    IPC2bits.T3IP = 0x01; // Set Timer3 Interrupt Priority Level
    
}

void Timer23_Start_g( uint32_t ms )
{
    uint16_t div;
    uint32_t period;
    switch(T2CONbits.TCKPS)
    {
        case 0: div=1;break;
        case 1: div=8;break;
        case 2: div=64; break;
        case 3: div=256; break;
        default:div=1;break;
    }
    period = SYSTEM_FOSC/2/div/1000*ms;
    PR3 = (period>>16) & 0xffff; // Load 32-bit period value (msw)
    PR2 = period & 0xffff; // Load 32-bit period value (lsw)
    
    IFS0bits.T3IF = 0; // Clear Timer3 Interrupt Flag
    IEC0bits.T3IE = 1; // Enable Timer3 interrupt
    T2CONbits.TON = 1; // Start 32-bit Timer
}

void Timer23_Stop_g( void )
{
    /* Stop the Timer */
    T2CONbits.TON = 0;

    /*Disable the interrupt*/
    IEC0bits.T3IE = 0;
}


//interrupt function


void __attribute__ ( ( interrupt, no_auto_psv ) ) _T3Interrupt (  )
{
    Timer23CallBack();

    IFS0bits.T3IF = 0; //clear flag
}